package com.kfh.ybracelet.mqtt;

import android.app.ActivityManager;
import android.app.Service;
import android.content.ComponentName;
import android.content.Context;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.media.AudioManager;
import android.media.SoundPool;
import android.os.Environment;
import android.os.Vibrator;
import android.support.annotation.NonNull;
import android.util.Log;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.kfh.ybracelet.R;
import com.kfh.ybracelet.base.HomeActivity;
import com.kfh.ybracelet.bean.MessageBean;
import com.kfh.ybracelet.bean.TopicBean;
import com.kfh.ybracelet.db.DatabaseManager;
import com.kfh.ybracelet.utils.CommonUtils;
import com.kfh.ybracelet.utils.Constant;
import com.kfh.ybracelet.utils.File2Code;
import com.kfh.ybracelet.utils.QiniuUtils;

import org.json.JSONException;

import java.io.File;
import java.io.IOException;
import java.util.Map;
import java.util.Set;
import java.util.UUID;

import de.greenrobot.event.EventBus;

/**
 * 聊天消息处理类
 * Created by Aaron on 16/3/25.
 */
public class ChatMessageManager {

    private Context ctx;
    private SharedPreferences sp;
    private int loadId;
    private SoundPool soundPool;
    private Vibrator vibrator;

    private ChatMessageManager() {
    }

    private static ChatMessageManager cm = new ChatMessageManager();

    public static ChatMessageManager getInstance() {
        return cm;
    }

    /**
     * 处理消息
     *
     * @param topic
     * @param message
     */
    public void handlerMessage(String topic, String message, Context ctx) {

        try {

            this.ctx = ctx;
            if (sp == null)
                sp = ctx.getSharedPreferences(Constant.CONFIG, Context.MODE_PRIVATE);

//            LogUtil.e("tag", " 收到消息的topic : " + topic);

//        //判断出消息类型
//        int chatType = getChatType(topic);

//**************************************************系统消息**********************************************************************//

            if (topic.startsWith(Constant.START_SYSTEM)) {
                handleSystemMessage(message);
                return;
            }

//**************************************************聊天消息**********************************************************************//

            handleChatMessage(topic, message);

        } catch (Exception e) {
            Log.e("tag", "接受消息出现了问题 消息:" + message);
        }


    }

    /**
     * 处理系统消息
     *
     * @param message 聊天的消息
     * @throws JSONException
     */
    private void handleSystemMessage(String message) throws JSONException {
        //系统消息
        org.json.JSONObject js = new org.json.JSONObject(message);

        String order = js.getString("order");
        String mTopic = js.getString("topic");

        if (Constant.SUB.equals(order)) {   //订阅主题

            js = new org.json.JSONObject(mTopic);

            updateInfo(js.getString("topic"), js.getString("topicPic"), js.getString("topicName"));

            MqttManager.getInstance().subTopicSingle(js.getString("topic"));

        } else if (Constant.UN_SUB.equals(order)) {     //取消订阅主题

            MqttManager.getInstance().unSubTopic(mTopic);

        }
    }

    /**
     * 处理聊天消息
     *
     * @param topic   聊天的topic
     * @param message 聊天的消息
     * @throws Exception
     */
    private void handleChatMessage(final String topic, String message) throws Exception {

        final MessageBean mb = JSONObject.parseObject(message, MessageBean.class);

        //是我自己发送的消息,已经存储到数据中了,无需再操作
        if (sp.getString(Constant.USERID, "").equals(mb.sendId))
            return;

        //过滤重复消息
        if (DatabaseManager.getInstance().hasReceived(ctx, topic, mb.sendDate, mb.sendId, sp.getString(Constant.USERID, ""))) {
            Log.e("tag", " === 重复消息 === ");
            return;
        }

        mb.receiverTime = System.currentTimeMillis() + "";
        mb.channelId = topic;
//        mb.chatType = getChatType(topic);

        if (Constant.MQTTMESSAGENOTICE.equals(mb.messageType)) {

            //增删群成员,群头像和群昵称可能会发生变化,需修改群信息(存在sp中的信息)
            //添加订阅信息, 内存中 和 sp 中都添加
            updateInfo(topic, mb.receivePic, mb.receiveName);

        }

        //群聊的话,更新头像
        if (topic.startsWith(Constant.START_GROUP) || topic.startsWith(Constant.START_CHILD))

            if (Constant.topicMap != null) {

                TopicBean topicBean = Constant.topicMap.get(topic);
                if (topicBean != null) {
                    mb.receivePic = topicBean.topicImg;
                    mb.receiveName = topicBean.topicName;
                }

            }

//        }

        switch (mb.messageType) {

            case Constant.MQTTMESSAGENOTICE: //创建群  加人 删人

                //消息 声音和铃声震动
                remainUser(topic);

                //数据库存储消息
                save2Table(mb, topic);

                noticePageUpdate(mb);

                break;

            case Constant.MQTTMESSAGETEXT://纯文本

                //消息 声音和铃声震动
                remainUser(topic);

                save2Table(mb, topic);

                noticePageUpdate(mb);

                break;

            case Constant.MQTTMESSAGEPHOTO: //图片

                String url = mb.content;

                //存储图片
                final String picPath = getHintFile() + "/" + UUID.randomUUID().toString() + ".jpg";

                receivePic(mb, picPath, topic);//先保存图片,防止重复消息时 子线程插入太慢 造成消息重复

//                Log.e("tag", "url : " + url);

                QiniuUtils.getBitmap(ctx, url, new QiniuUtils.PicSuccessListener() {
                            @Override
                            public void setOnSuccessListener(Bitmap bp) {

                                try {

                                    if (bp != null)
                                        CommonUtils.saveBitmap2Local(bp, picPath);

                                    //消息 声音和铃声震动
                                    remainUser(topic);

                                    noticePageUpdate(mb);

                                } catch (IOException e) {
                                    e.printStackTrace();
                                }

//                                //消息 声音和铃声震动
//                                remainUser(topic);
//
//                                noticePageUpdate(mb);

                                //因为加载图片有延迟, 所以在这里再更新下
                                if (isTopActivity()) {
                                    EventBus.getDefault().post(Constant.UPDATE_RED_COUNT);
                                }
                            }
                        }
                );

                break;

            case Constant.MQTTMESSAGEVOICE://语音

                //消息 声音和铃声震动
                remainUser(topic);

                // 先把语音保存到本地,再存储到数据库
                String videoPath = getHintFile() + "/" + UUID.randomUUID().toString() + ".amr";

                //存储语音文件
                File2Code.decoderBase64File(mb.content, videoPath);

//                    LogUtil.e("tag", "音频存储路径:" + videoPath);

                mb.content = videoPath;

                save2Table(mb, topic);

                noticePageUpdate(mb);

                break;

        }

        //判断homeactivity是否在顶部, 让homeactivity 更新小红点个数
        if (isTopActivity()) {
            EventBus.getDefault().post(Constant.UPDATE_RED_COUNT);
        }

    }

    private void noticePageUpdate(MessageBean mb) {
        mb.operationStyle = Constant.RECEIVE_MESSAGE;
        EventBus.getDefault().post(mb); //通知有新消息 (chatfragment页面 chatactivity页面)
    }

    private void receivePic(MessageBean mb, String picPath, String topic) {

        mb.content = picPath;

        save2Table(mb, topic);

    }

    /**
     * 更新群聊的信息
     *
     * @param topic  群聊的topic
     * @param imgUrl 群聊的url
     * @param name   群聊的昵称
     */
    private void updateInfo(String topic, String imgUrl, String name) {

        if (Constant.topicMap == null)
            Constant.topicMap = (Map<String, TopicBean>) JSON.parse(sp.getString(Constant.TOPIC_MAP, ""));

        TopicBean tb = new TopicBean();
        tb.topic = topic;
        tb.topicImg = imgUrl;
        tb.topicName = name;
        Constant.topicMap.put(topic, tb);

        sp.edit().putString(Constant.TOPIC_MAP, JSON.toJSONString(Constant.topicMap, true)).apply();

    }

    /**
     * 发出震动和声音提醒
     */
    private void remainUser(String topic) {

        //先判断手机是否是关闭了提示音
        AudioManager mAudioManager = (AudioManager) ctx.getSystemService(Context.AUDIO_SERVICE);
        int streamVolume = mAudioManager.getStreamVolume(AudioManager.STREAM_NOTIFICATION);

        Set<String> remaindSet = sp.getStringSet(Constant.REMAIND + sp.getString(Constant.USERID, ""), null);

        if (!(remaindSet != null && remaindSet.contains(topic))) {//需要提醒

            //是否需要声音提醒
            if (streamVolume > 0) {

                if (soundPool == null || loadId == 0) {
                    soundPool = new SoundPool(1, AudioManager.STREAM_MUSIC, 0);
                    loadId = soundPool.load(ctx, R.raw.gl, 1);
//            loadId = soundPool.load(ctx, R.raw.notificationsound, 1);

                    soundPool.setOnLoadCompleteListener(new SoundPool.OnLoadCompleteListener() {
                        @Override
                        public void onLoadComplete(SoundPool soundPool, int sampleId, int status) {
                            soundPool.play(loadId, 1, 1, 0, 0, 1);
                        }
                    });

                } else {// ==0表示加载失败, 否则表示加载成功
                    soundPool.play(loadId, 1, 1, 0, 0, 1);
                }

            }

            //震动提醒
            if (vibrator == null)
                vibrator = (Vibrator) ctx.getSystemService(Service.VIBRATOR_SERVICE);
            vibrator.vibrate(500);

        }

    }

    @NonNull
    private String getHintFile() {

        String cacheDirHint = Environment.getExternalStorageDirectory().getPath() + Constant.PHOTO_PATH_HINT;

        File photoHint = new File(cacheDirHint);

        if (!photoHint.exists()) {//创建隐藏文件夹
            photoHint.mkdirs();

            //再创建 .nomedia 文件nomedia
            File noMedia = new File(cacheDirHint + ".nomedia");
            if (!noMedia.exists()) {
                try {
                    noMedia.createNewFile();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            } else noMedia = null;

        }
        return cacheDirHint;
    }

    /**
     * 保存数据到数据库
     *
     * @param topic
     */
    private void save2Table(MessageBean mb, String topic) {

        if (mb == null)
            return;

        //往历史记录表里插入 聊天记录
        DatabaseManager.getInstance().insertHisData(ctx, new Object[]{mb.sendId, mb.sendName, mb.sendPic, mb.receiverTime,
                "0", mb.content, topic, mb.messageType, mb.receiveId, mb.receiveName, mb.receivePic,
                mb.voiceLength, mb.chatType, mb.sendDate, sp.getString(Constant.USERID, ""), Constant.UNLISTENER});

        //往最新的topic表中插入数据
        int count = 0;

        if (CommonUtils.isGroupChat(topic)) {//群聊

            if (CommonUtils.isNull(mb.receiveName)) { //如果没有群昵称等信息

                count = DatabaseManager.getInstance().updateTopicWithoutInfo(ctx, new String[]{mb.sendId, mb.sendName,
                        mb.sendPic, mb.receiverTime, mb.content,
                        mb.messageType, mb.voiceLength + "", mb.chatType + "", mb.sendDate + "", "1", topic, sp.getString(Constant.USERID, "")});

            } else { //有群昵称  群头像等信息

//                    topicName, sendId, sendName, sendPic, receiverTime, receiveId" +
//                ",content ,messageType,voiceLength,chatType,sendTime,receivePic, receiveName, isListener, isRead, topic, userId

                count = DatabaseManager.getInstance().updateTopic(ctx, new String[]{mb.receiveName, mb.sendId, mb.sendName,
                        mb.sendPic, mb.receiverTime, mb.receiveId, mb.content,
                        mb.messageType, mb.voiceLength + "", mb.chatType + "", mb.sendDate + "", mb.receivePic,
                        mb.receiveName, Constant.UNLISTENER + "", "1", topic, sp.getString(Constant.USERID, "")});
            }

        } else { //私聊

            count = DatabaseManager.getInstance().updateTopic(ctx, new String[]{mb.sendName, mb.sendId, mb.sendName,
                    mb.sendPic, mb.receiverTime, sp.getString(Constant.USERID, ""), mb.content,
                    mb.messageType, mb.voiceLength + "", mb.chatType + "", mb.sendDate + "",
                    sp.getString(Constant.USERIMG, ""), sp.getString(Constant.NICKNAME, ""), Constant.UNLISTENER + "",
                    "1", topic, sp.getString(Constant.USERID, "")});
        }
        mb.isRead = count;

    }

    private boolean isTopActivity() {
        boolean isTop = false;
        ActivityManager am = (ActivityManager) ctx.getSystemService(Context.ACTIVITY_SERVICE);
        ComponentName cn = am.getRunningTasks(1).get(0).topActivity;
        if (cn.getClassName().equals(HomeActivity.class.getName())) {
            isTop = true;
        }
        return isTop;
    }

}
